<?php

declare(strict_types=1);

namespace App\Aspect;

use App\Constants\ContextKey;
use App\Task\OperationLog\AdminTask;
use App\Task\OperationLog\CooperativeTask;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use ReflectionMethod;

/**
 * @Aspect
 */
class OperationLog extends AbstractAspect
{
    protected $container;

    public $classes = [
    ];

    public $annotations = [
        \App\Annotation\OperationLog::class
    ];

    /**
     * OperationLog constructor.
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
    }

    /**
     * @param ProceedingJoinPoint $proceedingJoinPoint
     * @return mixed
     * @throws \Hyperf\Di\Exception\Exception
     */
    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        //处理参数
        $arguments = $this->handleArg($proceedingJoinPoint);
        $result = $proceedingJoinPoint->process();
        //调用后处理
        $annotation = di(AnnotationCollector::class)::getClassMethodAnnotation($proceedingJoinPoint->className, $proceedingJoinPoint->methodName);
        foreach ($annotation as $val){
            switch ($val->platform){
                case 'admin':
                    $userInfo = \Hyperf\Utils\Context::get(ContextKey::ADMIN_USER);
                    $userInfo->event = $val->event;
                    $userInfo->arguments = $arguments;
                    $client = di(AdminTask::class);
                    $client->setLogData($userInfo);
                    break;
                case 'cooperative':
                    $userInfo = \Hyperf\Utils\Context::get(ContextKey::COOPERATIVE_USER);
                    $userInfo->event = $val->event;
                    $userInfo->arguments = $arguments;
                    $client = di(CooperativeTask::class);
                    $client->setLogData($userInfo);
                    break;
            }
        }
        return $result;
    }

    /**
     * 获取请求参数
     * @param $joinPoint
     * @return false|string
     * @throws \ReflectionException
     */
    public function handleArg($joinPoint)
    {
        $reflection = new ReflectionMethod($joinPoint->className, $joinPoint->methodName);
        $arg = [];
        $num = $reflection->getNumberOfParameters();
        foreach ($reflection->getParameters() as $val){
            $arg[] = $val->name;
        }
        $param = [];
        $arg = $joinPoint->getArguments();
        for ($i=0;$i<$num;$i++){
            if (is_object($arg[$i])){
               $param['post'] = $arg[$i]->getParsedBody();
               $param['get'] = $arg[$i]->getQueryParams();
            }else{
                array_push($param,$arg[$i]) ;
            }
        }

        return json_encode($param, JSON_UNESCAPED_SLASHES);
    }

}
